// 导入数据库模块
const db = require('../db/index')

// 工具类
const ResVo = require('../class/ResVo')
const Utils = require('../utils')

// 全局使用的表名
const tableName = 'adventuretasks'

// ** ---------- api 处理逻辑 ---------- **
// 分页查询
// limit [位置偏移量,] 行数 - 从0开始
// 功能：每页显示 pageSize 条数， 此时在 pageNum 页
// 分页公式: (当前页数 - 1) * 每页条数, 每页条数

// 任务列表
const getTaskList = async (req, res) => {
  try {
    // 获取 请求查询参数
    const { pageNum = 1, pageSize = 10, taskName } = req.query ?? {}

    // 1、查询所有未完成任务的数量
    const totalSql = `select count(*) as total from ${tableName} where task_completed = 0`

    const total = await getTaskTotal(totalSql)

    if (!total) {
      return res.send(ResVo.setPageRes(total))
    }

    // 2、搜索条件查询 - 使用DATE_FORMAT函数在数据库层进行日期的转化
    let sql = `SELECT 
    *,
    DATE_FORMAT(task_created_at, '%Y-%m-%d %H:%i:%s') AS create_time,
    DATE_FORMAT(task_updated_at, '%Y-%m-%d %H:%i:%s') AS update_time
FROM ${tableName}
WHERE task_completed = 0`
    if (taskName) {
      sql += ` and task_name like '%${taskName}%'`
    }

    // 3、分页查询
    sql += ` limit ${(pageNum - 1) * pageSize}, ${pageSize}`
    db.query(sql, (err, results) => {
      if (err) {
        return res.send(ResVo.err(err.message))
      }

      const transformedResults = Utils.transformedResults(results)

      res.send(ResVo.setPageRes(total, transformedResults))
    })
  } catch (err) {
    console.warn(err)
  }
}

// 新增任务
const addTask = async (req, res) => {
  try {
    // 1、入参
    const params = req.body

    // 2、sql 设置

    const fields = {
      taskName: 'task_name',
      taskLevel: 'task_level',
      taskType: 'task_type',
      taskDescription: 'task_description',
      monsterDescription: 'monster_description',
      taskReward: 'task_reward',
      taskLocation: 'task_location',
      taskTimeLimit: 'task_time_limit',
      taskPublisher: 'task_publisher',
      taskReceiver: 'task_receiver',
      taskDangerLevel: 'task_danger_level',
      taskPrerequisite: 'task_prerequisite',
      taskNotes: 'task_notes'
    }

    let insertFields = [] // 需要更新的数据库字段
    let sqlValues = [] // 字段的具体实参
    let placeholders = [] // 占位符

    for (let key in fields) {
      if (params[key] != null) {
        insertFields.push(`${fields[key]}`)
        placeholders.push('?')
        sqlValues.push(params[key])
      }
    }

    let sql = `insert into ${tableName} ( ${insertFields.join(
      ', '
    )} ) values ( ${placeholders.join(',')} )`

    // 3、sql 执行
    db.query(sql, sqlValues, (err, results) => {
      if (err || results.affectedRows !== 1) {
        return res.send(ResVo.err(err.message))
      }
      res.send(ResVo.success())
    })
  } catch (err) {
    console.warn(err)
  }
}

// 编辑任务
const updateTask = async (req, res) => {
  // 1、入参
  const params = req.body

  if (!params.taskId) {
    return res.send(ResVo.err('任务主键ID异常'))
  }

  // 2、sql 设置

  const fields = {
    taskName: 'task_name',
    taskLevel: 'task_level',
    taskType: 'task_type',
    taskDescription: 'task_description',
    monsterDescription: 'monster_description',
    taskReward: 'task_reward',
    taskLocation: 'task_location',
    taskTimeLimit: 'task_time_limit',
    taskPublisher: 'task_publisher',
    taskReceiver: 'task_receiver',
    taskDangerLevel: 'task_danger_level',
    taskPrerequisite: 'task_prerequisite',
    taskNotes: 'task_notes'
  }

  /*
  1、将一个包含字段名和对应数据库字段的映射关系对象fields转换为一个Map对象fieldsMap。
  2、fieldsMap中存储了字段名和数据库字段的映射关系。这样可以方便地通过字段名快速查找对应的数据库字段 
  3、Object.entries(fields)将fields对象转换为一个二维数组，每个元素是一个键值对的数组
  */
  const fieldsMap = new Map(Object.entries(fields))
  let updateSql = `update ${tableName} set `

  let updateFields = [] // 需要更新的数据库字段
  let sqlValues = [] // 字段的具体实参

  for (let key of fieldsMap.keys()) {
    if (params[key]) {
      updateFields.push(`${fields[key]} = ?`)
      sqlValues.push(params[key])
    }
  }

  updateSql += updateFields.join(', ') // 注意有空格
  updateSql += ` where task_id =  ${params.taskId}`

  // 3、sql 执行
  db.query(updateSql, sqlValues, (err, results) => {
    if (err || results.affectedRows !== 1) {
      return res.send(ResVo.err(err.message))
    }

    res.send(ResVo.success())
  })
}

// 删除任务
const delTask = async (req, res) => {
  const { taskId } = req.params
  const delSql = `delete from adventuretasks where taskId = ?`

  db.query(delSql, taskId, (err, results) => {
    if (err || results.affectedRows !== 1) {
      return res.send(ResVo.err(err.message))
    }

    res.send(ResVo.success())
  })
}

// 查看任务详情
const getDetail = async (req, res) => {
  try {
    if (!req.params.taskId) {
      return res.send(ResVo.err('任务主键ID异常'))
    }
    const data = await getTaskByTaskId(req.params.taskId)
    res.send(ResVo.setData(data))
  } catch (err) {
    res.send(ResVo.err(err.message))
  }
}

// ** ---------- api 处理逻辑 End---------- **

// ** ---------- func ---------- **

// 查询任务列表总数
function getTaskTotal(sql) {
  return new Promise((resolve, reject) => {
    db.query(sql, (err, results) => {
      if (err) {
        reject(err)
      }
      if (results.length > 0) {
        resolve(results[0].total)
      } else {
        resolve(0)
      }
    })
  })
}

// 根据taskId 获取信息
function getTaskByTaskId(taskId) {
  const sql = `select * from ${tableName} where task_id = ?`
  return new Promise((resolve, reject) => {
    db.query(sql, taskId, (err, results) => {
      if (err) {
        reject(err)
      }
      const transformedResults = Utils.transformedResults(results)

      if (transformedResults.length > 0) {
        resolve(transformedResults?.[0])
      } else {
        resolve(null)
      }
    })
  })
}

// ** ---------- func End---------- **

// 暴露方法
module.exports = {
  getTaskList,
  addTask,
  updateTask,
  delTask,
  getDetail
}
